package com.katesoft.scale4j.persistent.spring.postprocessor;

import com.katesoft.scale4j.common.spring.AbstractBeanPropertiesOverridePostProcessor;
import net.jcip.annotations.ThreadSafe;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
import org.springframework.core.Ordered;
import org.springframework.transaction.jta.JtaTransactionManager;

import java.util.Properties;

import static com.katesoft.scale4j.common.services.IBeanNameReferences.TRANSACTION_SERVICE;
import static com.katesoft.scale4j.common.spring.IPostProcessingOrder.TRANSACTION_POST_PROCESSOR_PRIORITY;

/**
 * This post processor allows to override configuration for {@link JtaTransactionManager}, which is defined inside jvmcluster persistent module.
 *
 * @author kate2007
 */
@ThreadSafe
public class TransactionManagerConfigurationPostProcessor extends AbstractBeanPropertiesOverridePostProcessor implements InitializingBean, Ordered
{
    private Properties transactionManagerProperties;

    public TransactionManagerConfigurationPostProcessor()
    {
        setTargetBean(TRANSACTION_SERVICE);
        setOrder(TRANSACTION_POST_PROCESSOR_PRIORITY);
    }

    @SuppressWarnings({"unchecked"})
    @Override
    protected void doPostProcessing(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException
    {
        if (transactionManagerProperties != null) {
            ValueHolder argumentValue = constructorArgumentValues.getArgumentValue(0, Properties.class);
            Properties props = (Properties) argumentValue.getValue();
            logger.info("adding transactionManager properties %s to existing properties %s", transactionManagerProperties, props);
            props.putAll(transactionManagerProperties);
        }
    }

    @Override
    public void afterPropertiesSet()
    {
        logger.info("Using TransactionManagerBeanName = %s, transactionManagerProperties = %s for post processing", getTargetBean(),
                    transactionManagerProperties);
    }

    public void setTransactionManagerProperties(final Properties transactionManagerProperties)
    {
        this.transactionManagerProperties = transactionManagerProperties;
    }
}
